trasa-reflex-0.1.0.0: src/Reflex/PopState.hs
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE FlexibleContexts #-}
{-# OPTIONS_GHC -Wall -Werror #-}
module Reflex.PopState (url) where
import qualified Data.Text as T
import Reflex.Class (Reflex(..),MonadHold(..),ffor)
import Reflex.PerformEvent.Class (PerformEvent(..))
import Reflex.TriggerEvent.Class (TriggerEvent)
import Reflex.Dom.Builder.Immediate (wrapDomEvent)
import Language.Javascript.JSaddle (eval,call)
import GHCJS.DOM (currentWindowUnchecked)
import GHCJS.DOM.Types (MonadJSM,liftJSM,ToJSVal(..))
import GHCJS.DOM.EventM (on)
import GHCJS.DOM.Window (getLocation)
import GHCJS.DOM.WindowEventHandlers (popState)
import GHCJS.DOM.Location (getPathname)
import Trasa.Core (Url,decodeUrl,encodeUrl)
getPopState :: (Reflex t, TriggerEvent t m, MonadJSM m) => m (Event t Url)
getPopState = do
window <- currentWindowUnchecked
wrapDomEvent window (`on` popState) $ do
loc <- getLocation window
locStr <- getPathname loc
(return . decodeUrl) locStr
-- | The starting location and a stream of popstate urls
url :: (MonadHold t m, TriggerEvent t m, PerformEvent t m, MonadJSM (Performable m), MonadJSM m) =>
Event t Url -> m (Url, Event t Url)
url us = do
u0 <- liftJSM $ do
window <- currentWindowUnchecked
loc <- getLocation window
locStr <- getPathname loc
(return . decodeUrl) locStr
performEvent_ $ ffor us $ \uri -> liftJSM $ do
f <- eval ("(function (url) { window[\"history\"][\"pushState\"](0,\"\",url) })" :: T.Text)
jsUri <- toJSVal (encodeUrl uri)
_ <- call f f [jsUri]
return ()
ps <- getPopState
return (u0, ps)