0

For an SDK add-on, I am trying to detect, on right-click, the closest page anchor (as described here).

Since JavaScript apparently has no way to query the mouse coordinates without first creating a mouse event listener, and since I don't want an expensive mouseover listener running all of the time on every single page! (and polling to rebuild a mouse listener is ugly and not fully accurate anyways), I was hoping I could get the mouse coordinates from a click event. Unfortunately, although self.on('click' does fire:

  1. This event is without an event object from which mouse coordinates could be obtained
  2. Adding a normal window.addEventListener('click',... listener doesn't actually get fired in the SDK content script with the first menu selection for some reason (it does fire subsequently, however).

Here is my workaround, but I want to fire on the current exact coordinates, not the coordinates of the node:

var x, y;
window.addEventListener('click', function (e) {
    if (e.button === 2) {
        x = e.clientX;
        y = e.clientY;
    }
}, true);

self.on('click', function (node) {
    if (!x) { // Since this is not showing the first time, we fire on the node (which is specifically an element, not a text node), though we really want the real clientX and clientY where the mouse is, not this simulation based on where the element is
        node.dispatchEvent(new MouseEvent('click', {
            button: 2
        }));
    }
    // Use document.caretPositionFromPoint with x and y to determine location of text

Is there any other way to get the actual mouse coordinates?

Community
  • 1
  • 1
Brett Zamir
  • 14,034
  • 6
  • 54
  • 77
  • I cannot really reproduce this. The `addEventListener("click", ...)` always fires before `self.on("click", ...)` when I tried it. Can you elaborate please? – nmaier Jun 26 '14 at 05:13
  • For me, the problem only occurs for the very first attempt on loading the page. Reloading the page causes the same thing to happen again: the first attempt fails to detect correctly (detects too high by going through the `if (!x)` workaround due to the missing click event), but subsequent context menu invocations do work properly. Tested against SDK 1.16 with FF 31.0. – Brett Zamir Jun 26 '14 at 05:25
  • You're testing using the code from https://github.com/brettz9/jump-to-anchor , right? – nmaier Jun 26 '14 at 05:27
  • Right...in the current master branch... Sometimes it goes to anchor 2.3.2 , but that is still too high--if clicking in section 2.3.3, it should go to 2.3.3 – Brett Zamir Jun 26 '14 at 05:37
  • and when I added logging, nothing showed up in the `window.addEventListener('click'` code until after the first attempt... – Brett Zamir Jun 26 '14 at 05:38
  • Nope, cannot reproduce on Fx31 OSX, having tested `cfx run` and a fresh profile + `cfx xpi`. Maybe something OS/platform specific? – nmaier Jun 26 '14 at 05:41
  • Maybe---I'm on Windows...Also trying with either `cfx run` or `cfx xpi` (just now also on a new profile). – Brett Zamir Jun 26 '14 at 05:46
  • Maybe a viable work-around could be to not immediately execute code in `self.on("click", ...)` but instead issue a `setTimeout(code, 0)` to wait for the current event queue to finish dispatching? – nmaier Jun 26 '14 at 08:54
  • Nice idea but even 10,000 ms didn't do the trick... the only reported logging of the click was the one caused by my simulated event after 10 secs. – Brett Zamir Jun 26 '14 at 11:15

1 Answers1

1

You can actually query the mouse coordinates without a mouse listener.

This page has a bunch of examples: https://developer.mozilla.org/en-US/docs/Mozilla/js-ctypes/Standard_OS_Libraries

It has to be done on per OS basis though as it uses JS-Ctypes. If you're worried about performance don't fear at all. You can use the code asynchronously via ChromeWorkers

Blagoh
  • 1,225
  • 1
  • 14
  • 29
  • Fascinating--would have been nice if it could have been without an OS dependency, but that is quite cool, thanks! – Brett Zamir Jul 02 '14 at 22:27
  • :O @nmaier got out thunk by a new user!! props man, may be your first and last time tho :P – Noitidart Jul 02 '14 at 23:23
  • FTR, although this solution does indeed get coordinates nicely, in my case I needed the coordinates at the time the user clicked down to get the menu, not at the time the user clicked the specific item (as is the time the add-on script can get notified). I worked around the issue by associating a pageMod to the cm (as per http://stackoverflow.com/a/11768820/271577 ) and the pageMod has no trouble with the `click` event. – Brett Zamir Jul 03 '14 at 00:17
  • Maybe a `postMessage` in the "context" event would have worked to get the coordinates at the right time, but I needed a way to communicate back to the content anyways (and nicer not to need OS-specific code). – Brett Zamir Jul 03 '14 at 00:17