{-# LANGUAGE AllowAmbiguousTypes #-}
{-# LANGUAGE LambdaCase #-}
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE TemplateHaskell #-}
module Shpadoinkle.Html.Event where
import Control.Monad (msum)
import Data.Text
import Language.Javascript.JSaddle
import Shpadoinkle
import Shpadoinkle.Html.TH
import Shpadoinkle.Keyboard
onInput' :: MonadJSM m => (Text -> m a) -> (Text, Prop m a)
onInput' f = listenRaw "input" $ \(RawNode n) _ ->
f =<< liftJSM (valToText =<< unsafeGetProp "value" =<< valToObject n)
onInput :: MonadJSM m => (Text -> a) -> (Text, Prop m a)
onInput f = onInput' (pure . f)
mkOnKey :: MonadJSM m => Text -> (KeyCode -> m a) -> (Text, Prop m a)
mkOnKey t f = listenRaw t $ \_ (RawEvent e) ->
f =<< liftJSM (fmap round $ valToNumber =<< unsafeGetProp "keyCode" =<< valToObject e)
onKeyup, onKeydown, onKeypress :: MonadJSM m => (KeyCode -> m a) -> (Text, Prop m a)
onKeyup = mkOnKey "keyup"
onKeydown = mkOnKey "keydown"
onKeypress = mkOnKey "keypress"
onKeyup', onKeydown', onKeypress' :: MonadJSM m => (KeyCode -> a) -> (Text, Prop m a)
onKeyup' f = onKeyup (pure . f)
onKeydown' f = onKeydown (pure . f)
onKeypress' f = onKeypress (pure . f)
onCheck' :: MonadJSM m => (Bool -> m a) -> (Text, Prop m a)
onCheck' f = listenRaw "update" $ \(RawNode n) _ ->
f =<< liftJSM (valToBool =<< unsafeGetProp "checked" =<< valToObject n)
onCheck :: MonadJSM m => (Bool -> a) -> (Text, Prop m a)
onCheck f = onCheck' (pure . f)
onSubmit' :: MonadJSM m => m a -> (Text, Prop m a)
onSubmit' m = listenRaw "submit" $ \_ (RawEvent e) ->
liftJSM (valToObject e # ("preventDefault" :: String) $ ([] :: [()])) >> m
onSubmit :: MonadJSM m => a -> (Text, Prop m a)
onSubmit = onSubmit' . pure
mkGlobalKey :: Text -> (KeyCode -> JSM ()) -> JSM ()
mkGlobalKey n t = do
d <- makeObject =<< jsg ("window" :: Text)
f <- toJSVal . fun $ \_ _ -> \case
e:_ -> t =<<
fmap round (valToNumber =<< unsafeGetProp "keyCode" =<< valToObject e)
_ -> return ()
unsafeSetProp (toJSString $ "on" <> n) f d
globalKeyDown, globalKeyUp, globalKeyPress :: (KeyCode -> JSM ()) -> JSM ()
globalKeyDown = mkGlobalKey "keydown"
globalKeyUp = mkGlobalKey "keyup"
globalKeyPress = mkGlobalKey "keypress"
$(msum <$> mapM mkEventDSL
[ "click"
, "contextmenu"
, "dblclick"
, "mousedown"
, "mouseleave"
, "mousemove"
, "mouseover"
, "mouseout"
, "mouseup"
, "beforeunload"
, "error"
, "hashchange"
, "load"
, "pageshow"
, "pagehide"
, "resize"
, "scroll"
, "unload"
, "blur"
, "change"
, "focus"
, "focusin"
, "focusout"
, "invalid"
, "reset"
, "search"
, "select"
, "drag"
, "dragend"
, "dragenter"
, "dragleave"
, "dragover"
, "dragstart"
, "drop"
, "copy"
, "cut"
, "paste"
, "afterprint"
, "beforeprint"
, "abort"
, "canplay"
, "canplaythrough"
, "durationchange"
, "emptied"
, "ended"
, "loadeddata"
, "loadedmetadata"
, "loadstart"
, "pause"
, "play"
, "playing"
, "progress"
, "ratechange"
, "seeked"
, "seeking"
, "stalled"
, "suspend"
, "timeupdate"
, "volumechange"
, "waiting"
, "animationend"
, "animationiteration"
, "animationstart"
, "message"
, "open"
, "mousewheel"
, "online"
, "offline"
, "popstate"
, "show"
, "storage"
, "toggle"
, "wheel"
, "touchcancel"
, "touchend"
, "touchmove"
, "touchstart" ])