@@ -47,45 +47,46 @@ data RouteContext segment t = RouteContext
4747 }
4848
4949
50−class (Reflex t, Monad m) => HasRoute segment t m | m -> segment, m -> t where
50+class (Reflex t, Monad m) => HasRoute t segment m | m -> segment, m -> t where
5151 routeContext :: m (RouteContext segment t)
5252 withSegments :: (RouteContext segment t -> RouteContext segment t) -> m a -> m a
5353
5454
55−newtype RouteT segment t m a = RouteT { unRouteT :: ReaderT (RouteContext segment t) m a }
55+newtype RouteT t segment m a = RouteT { unRouteT :: ReaderT (RouteContext segment t) m a }
5656 deriving (Functor, Applicative, Monad, MonadIO, MonadFix, MonadHold t,
5757 MonadSample t, MonadAsyncException, MonadException, MonadTrans, PostBuild t,
5858 MonadReflexCreateTrigger t, TriggerEvent t, MonadAtomicRef)
5959
60−instance (MonadWidget t m) => HasRoute segment t (RouteT segment t m) where
60+
61+instance (MonadWidget t m) => HasRoute t segment (RouteT t segment m) where
6162 routeContext = RouteT ask
6263 withSegments f (RouteT m) = RouteT $ local f m
6364
64−instance Requester t m => Requester t (RouteT segment t m) where
65− type Request (RouteT segment t m) = Request m
66− type Response (RouteT segment t m) = Response m
65+instance Requester t m => Requester t (RouteT t segment m) where
66+ type Request (RouteT t segment m) = Request m
67+ type Response (RouteT t segment m) = Response m
6768 requesting = lift . requesting
6869 requesting_ = lift . requesting_
6970
70−instance HasRoute segment t m => HasRoute segment t (RequesterT t request response m) where
71+instance HasRoute t segment m => HasRoute t segment (RequesterT t request response m) where
7172 routeContext = lift routeContext
7273 withSegments f (RequesterT a) = RequesterT $ StrictState.mapStateT (mapReaderT $ withSegments f) a
7374
74−instance Wrapped (RouteT segment t m a) where
75− type Unwrapped (RouteT segment t m a) = ReaderT (RouteContext segment t) m a
75+instance Wrapped (RouteT t segment m a) where
76+ type Unwrapped (RouteT t segment m a) = ReaderT (RouteContext segment t) m a
7677 _Wrapped' = iso coerce coerce
7778
78−instance RouteT segment t m a ~ x => Rewrapped (RouteT segment t m a) x
79+instance RouteT t segment m a ~ x => Rewrapped (RouteT t segment m a) x
7980
80−instance PerformEvent t m => PerformEvent t (RouteT segment t m) where
81− type Performable (RouteT segment t m) = Performable m
81+instance PerformEvent t m => PerformEvent t (RouteT t segment m) where
82+ type Performable (RouteT t segment m) = Performable m
8283 {-# INLINABLE performEvent_ #-}
8384 performEvent_ = lift . performEvent_
8485 {-# INLINABLE performEvent #-}
8586 performEvent = lift . performEvent
8687
87−instance MonadRef m => MonadRef (RouteT segment t m) where
88− type Ref (RouteT segment t m) = Ref m
88+instance MonadRef m => MonadRef (RouteT t segment m) where
89+ type Ref (RouteT t segment m) = Ref m
8990 {-# INLINABLE newRef #-}
9091 newRef = lift . newRef
9192 {-# INLINABLE readRef #-}
@@ -93,14 +94,14 @@ instance MonadRef m => MonadRef (RouteT segment t m) where
9394 {-# INLINABLE writeRef #-}
9495 writeRef r = lift . writeRef r
9596
96−instance (MonadAdjust t m, MonadHold t m) => MonadAdjust t (RouteT segment t m) where
97+instance (MonadAdjust t m, MonadHold t m) => MonadAdjust t (RouteT t segment m) where
9798 runWithReplace a0 a' = RouteT $ runWithReplace (unRouteT a0) (fmapCheap unRouteT a')
9899 traverseDMapWithKeyWithAdjust f dm edm = RouteT $ traverseDMapWithKeyWithAdjust (\k v -> unRouteT $ f k v) (coerce dm) (coerceEvent edm)
99100 {-# INLINABLE traverseDMapWithKeyWithAdjust #-}
100101 traverseDMapWithKeyWithAdjustWithMove f dm edm = RouteT $ traverseDMapWithKeyWithAdjustWithMove (\k v -> unRouteT $ f k v) (coerce dm) (coerceEvent edm)
101102
102−instance (DomBuilder t m, MonadHold t m, MonadFix m) => DomBuilder t (RouteT segment t m) where
103− type DomBuilderSpace (RouteT segment t m) = DomBuilderSpace m
103+instance (DomBuilder t m, MonadHold t m, MonadFix m) => DomBuilder t (RouteT t segment m) where
104+ type DomBuilderSpace (RouteT t segment m) = DomBuilderSpace m
104105 textNode = lift . textNode
105106 element elementTag cfg (RouteT child) = RouteT $ element elementTag cfg child
106107 inputElement = lift . inputElement
@@ -109,29 +110,30 @@ instance (DomBuilder t m, MonadHold t m, MonadFix m) => DomBuilder t (RouteT seg
109110 placeRawElement = lift . placeRawElement
110111 wrapRawElement e = lift . wrapRawElement e
111112
112−instance MonadReader r m => MonadReader r (RouteT segment t m) where
113+instance MonadReader r m => MonadReader r (RouteT t segment m) where
113114 ask = lift ask
114115 local f (RouteT a) = RouteT $ mapReaderT (local f) a
115116
116−instance MonadState s m => MonadState s (RouteT segment t m) where
117− get = lift get
118− put s = lift $ put s
117+deriving instance MonadState s m => MonadState s (RouteT t segment m)
119118
120−instance EventWriter t w m => EventWriter t w (RouteT segment t m) where
121− tellEvent = lift . tellEvent
119+instance HasRoute t segment m => HasRoute t segment (EventWriterT t w m) where
120+ routeContext = lift routeContext
121+ withSegments f (EventWriterT a) = EventWriterT $ StrictState.mapStateT (withSegments f) a
122122
123+instance EventWriter t w m => EventWriter t w (RouteT t segment m) where
124+ tellEvent = lift . tellEvent
123125
124−instance HasDocument m => HasDocument (RouteT segment t m)
125−instance HasJSContext m => HasJSContext (RouteT segment t m) where
126− type JSContextPhantom (RouteT segment t m) = JSContextPhantom m
126+instance HasDocument m => HasDocument (RouteT t segment m)
127+instance HasJSContext m => HasJSContext (RouteT t segment m) where
128+ type JSContextPhantom (RouteT t segment m) = JSContextPhantom m
127129 askJSContext = RouteT askJSContext
128130#ifndef ghcjs_HOST_OS
129−instance MonadJSM m => MonadJSM (RouteT segment t m)
131+instance MonadJSM m => MonadJSM (RouteT t segment m)
130132#endif
131133
132134
133−instance PrimMonad m => PrimMonad (RouteT segment t m) where
134− type PrimState (RouteT segment t m) = PrimState m
135+instance PrimMonad m => PrimMonad (RouteT t segment m) where
136+ type PrimState (RouteT t segment m) = PrimState m
135137 primitive = lift . primitive
136138
137139--instance HasMountStatus t m => HasMountStatus t (RouteT segment r m) where
@@ -141,7 +143,7 @@ instance PrimMonad m => PrimMonad (RouteT segment t m) where
141143runRoute :: forall segment t m. (MonadWidget t m, Eq segment)
142144 => (forall a. URIRef a -> [segment])
143145 -> (forall a. URIRef a -> [segment] -> URIRef a)
144− -> RouteT segment t m (Event t [segment])
146+ -> RouteT t segment m (Event t [segment])
145147 -> m ()
146148runRoute toSegments fromSegments (RouteT f) = do
147149 let
@@ -167,7 +169,7 @@ runRoute toSegments fromSegments (RouteT f) = do
167169
168170runRouteWithPathInFragment
169171 :: forall t m. (MonadWidget t m)
170− => RouteT Text t m (Event t [Text])
172+ => RouteT t Text m (Event t [Text])
171173 -> m ()
172174runRouteWithPathInFragment = runRoute
173175 (T.splitOn "/" . T.dropAround (=='/') . fragAsText)
@@ -175,7 +177,7 @@ runRouteWithPathInFragment = runRoute
175177
176178
177179withRoute
178− :: forall a segment t m. (DomBuilder t m, MonadFix m, PostBuild t m, MonadHold t m, HasRoute segment t m, Eq segment)
180+ :: forall a segment t m. (DomBuilder t m, MonadFix m, PostBuild t m, MonadHold t m, HasRoute t segment m, Eq segment)
179181 => (Maybe segment -> m a)
180182 -- ^ A routing function that produces a widget from a segment.
181183 -> m (Event t a)
@@ -209,18 +211,26 @@ withRoute f = do
209211 switchPromptly never =<< dyn component
210212
211213
212−allRouteSegments :: (Reflex t, MonadHold t m, MonadFix m, HasRoute segment t m, Eq segment) => m (Dynamic t [segment])
214+allRouteSegments :: (MonadHold t m, MonadFix m, HasRoute t segment m, Eq segment) => m (Dynamic t [segment])
213215allRouteSegments = _routeContext_allSegments <$> routeContext
214216
215−currentRouteSegment :: (Functor m, HasRoute segment t m) => m (Dynamic t (Maybe segment))
217+currentRouteSegment :: (Functor m, HasRoute t segment m) => m (Dynamic t (Maybe segment))
216218currentRouteSegment = _routeContext_currentSegment <$> routeContext
217219
218−nextRouteSegment :: (Reflex t, MonadHold t m, MonadFix m, HasRoute segment t m, Eq segment) => m (Dynamic t (Maybe segment))
220+nextRouteSegment :: (MonadHold t m, MonadFix m, HasRoute t segment m, Eq segment) => m (Dynamic t (Maybe segment))
219221nextRouteSegment = do
220222 ctx <- routeContext
221223 holdUniqDyn (listToMaybe <$> _routeContext_nextSegments ctx)
222224
223−redirectLocally :: (MonadWidget t m, HasRoute segment t m) => [segment] -> m (Event t [segment])
225+parentRouteSegments :: (MonadHold t m, MonadFix m, HasRoute t segment m, Eq segment) => m (Dynamic t [segment])
226+parentRouteSegments = do
227+ ctx <- routeContext
228+ holdUniqDyn $ do
229+ allSegments <- _routeContext_allSegments ctx
230+ nBelow <- length <$> _routeContext_nextSegments ctx
231+ pure $ take (length allSegments - nBelow) allSegments
232+
233+redirectLocally :: (PostBuild t m) => [segment] -> m (Event t [segment])
224234redirectLocally segments = (segments <$) <$> getPostBuild
225235
226236
@@ -233,3 +243,6 @@ fragAsText uri = maybe "" decodeUtf8 (uri ^. fragmentL)
233243pathSegments :: URIRef a -> [ByteString]
234244pathSegments uri = uri ^. pathL . to (B8.split '/')
235245
246+-- ^ Like 'switchPromptly' but without being prompt.
247+switchTardy :: (MonadHold t m, Reflex t) => Event t (Event t a) -> m (Event t a)
248+switchTardy x = switch <$> hold never x