Can't get `dispatchEvent` to fire in GHCJS

141 views Asked by At

The goal is to get window.addEventListener("popstate", ... to fire from an event dispatched from GHCJS code.


Tried so far

GHCJS.DOM doesn't work

w <- currentWindowUnchecked
e <- newPopStateEvent "popstate" Nothing
dispatchEvent_ w e

Language.Javascript.JSaddle doesn't work

e <- newPopStateEvent "popstate" Nothing
jsg "window" ^. jsf "dispatchEvent" (toJSVal e)

FFI doesn't work

foreign import javascript unsafe "window.dispatchEvent($1)" dispatchIt :: JSVal -> JSM ()

e <- newPopStateEvent "popstate" Nothing
dispatchIt =<< toJSVal e

Debugging output

This does work:

e <- newPopStateEvent "popstate" Nothing
w <- currentWindowUnchecked
jsg "console" ^. js2 "log" (toJSVal e) (toJSVal w)

And produces and interesting result

enter image description here

As you can see the JSVals are correct, and we can run the command in the JavaScript console.

Latest attempt

Then I discovered that if I throw an error right after dispatchEvent, it fires.

foreign import javascript unsafe "window.foo()" foo :: JSM ()

w <- currentWindowUnchecked
e <- newPopStateEvent "popstate" Nothing
dispatchEvent_ w e
liftJSM foo

This causes the expected result with dispatchEvent_, but obviously wont do, as it causes a runtime error.

So I thought it might be a syncPoint

Still no dice

!e <- newPopStateEvent ("popstate" :: Text) Nothing
!() <- dispatchEvent_ w e                                                                                     
liftJSM GHCJS.DOM.syncPoint  

Run the code

You can try this out for yourself

git clone -b crud-example https://gitlab.com/fresheyeball/Shpadoinkle.git
cd Shpadoinkle
./examples/servant-crud/run-crud.sh

open localhost:8080 in your browser, and click on the word "ECHO".

Relevant code:

https://gitlab.com/fresheyeball/Shpadoinkle/blob/crud-example/router/Shpadoinkle/Router.hs#L100 https://gitlab.com/fresheyeball/Shpadoinkle/blob/crud-example/examples/servant-crud/View.hs#L43

0

There are 0 answers