How can I pass events on to a hidden ?

2019-09-19 13:03发布

I've working on a simple view around a browser using XULRunner 1.9.2.

<?xml version="1.0"?>
<?xml-stylesheet type="text/css" href="chrome://global/skin/"?>
<window
    xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
    xmlns:html="http://www.w3.org/1999/xhtml">
  <hbox equalsize="always" flex="2">
    <browser flex="1" type="content-primary"/>
    <html:canvas flex="1"/>
  </hbox>
</window>

I've written some Javascript that handles MozAfterPaint events from the <browser>, pushes them to the <canvas> with drawWindow, and then does some magic. It all works fairly nicely. (Well, scrollbars and cursors are kinda wonky, but I can ignore those.)

I really want the canvas to be the only visible element, but I can only interact with the browser element right now.

What I've had partial success with:

  • Capture events on the <canvas> and re-inject them into the <browser>.

    I can use the clientX and clientY of each event to the canvas, look up the corresponding document.elementFromPoint(x, y) in the browser, and createEvent initEvent dispatchEvent appropriately.

    However, this only works well for key(down/press/up), click, and mouse(down/move/up). I don't see how to reasonably synthesize mouse(over/out) events, and DOMMouseScroll doesn't fire here so I can't capture scroll wheel events.

What I've had no success with:

  • Stacking the canvas above the browser.

    <stack flex="2">
      <browser flex="1" type="content-primary"/>
      <html:canvas flex="1"/>
    </stack>
    

    This requires some way of allowing events to pass through the canvas and onto the browser instead, which I haven't really tried yet, because there's a more immediate problem:

    Even though the canvas should be stacked above the browser, the browser is visible above the canvas.

  • Stack the browser above the canvas while making it transparent.

    <stack flex="2">
      <html:canvas flex="1"/>
      <browser flex="1" type="content-primary" style="opacity: 0;"/>
    </stack>
    

    In theory, I shouldn't have to mess with events at all this way. However, the opacity setting doesn't seem to do any good, and again, the browser still occludes the canvas.

How do I hide the browser yet still allow normal interaction with it?


(I'm not adverse to writing native code, and WebKit answers are fine too. But as far as I can tell, neither Gecko nor WebKit have off-screen rendering APIs, and there's no WebKit equivalents to MozAfterPaint and drawWindow.)

1条回答
\"骚年 ilove
2楼-- · 2019-09-19 13:14

As I recall you can do this by using mousethrough="always" attribute but I'm not sure that you can set it directly on the <canvas> element itself, so you may need to wrap it inside some sort of box. Otherwise as you're using XULRunner 1.9.2 I believe the pointer-events: none; CSS property can be used instead.

查看更多
登录 后发表回答