Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
57 changes: 4 additions & 53 deletions Quickref.md
Original file line number Diff line number Diff line change
Expand Up @@ -76,30 +76,7 @@ Note the "list" functions do not imply particular HTML tags (ul, li, etc), thoug
-- Same as dyn, but takes initial value and an update Event instead of a Dynamic.
[W] widgetHold :: m a -> Event (m a) -> m (Dynamic a)

-- Turn a Dynamic key/value map into a set of dynamically-changing widgets.
[W] listWithKey :: Ord k =>
Dynamic (Map k v) -> (k -> Dynamic v -> m a ) -> m (Dynamic (Map k a))

-- Same as above where the widget constructor doesn't care about the key.
[W] list :: Ord k =>
Dynamic (Map k v) -> ( Dynamic v -> m a ) -> m (Dynamic (Map k a))

-- Even simpler version where there are no keys and we just use a list.
[W] simpleList ::
Dynamic [v] -> ( Dynamic v -> m a ) -> m (Dynamic [a])

-- Like listWithKey specialized for widgets returning (Event a).
[W] listViewWithKey :: Ord k =>
Dynamic (Map k v) -> (k -> Dynamic v -> m (Event a)) -> m (Event (Map k a))

-- Create a dynamically-changing set of widgets, one of which is selected at any time.
[W] selectViewListWithKey_ :: Ord k => Dynamic k ->
Dynamic (Map k v) -> (k -> Dynamic v -> Dynamic Bool -> m (Event a)) -> m (Event k)

-- Same as listWithKey, but takes initial values and an updates Event instead of a Dynamic.
[W] listWithKey' :: Ord k =>
Map k v -> Event (Map k (Maybe v)) -> (k -> v -> Event v -> m a) -> m (Dynamic (Map k a))
```
Also see the "Collection management functions" section in the `reflex` Quick Reference.

### Utility widgets

Expand Down Expand Up @@ -135,27 +112,12 @@ Some of these widget builders take a configuration record and return a record co

## Connecting to the real world (I/O)

### Connecting to DOM events

```haskell
-- Extract the specified Event from an 'El'. See Reflex.Dom.Widget.Basic
[ ] domEvent :: EventName en -> El -> Event (EventResultType en)
```

### Performing arbitrary I/O in response to Events

```haskell
-- Run side-effecting actions in Event when it occurs; returned Event contains
-- results. Side effects run in (WidgetHost m) monad, which includes [S] and [H]
-- and can also do I/O via liftIO
[W] performEvent :: Event ( WidgetHost m a) -> m (Event a)

-- Just run side-effects; no return Event
[W] performEvent_ :: Event ( WidgetHost m ()) -> m ()

-- Actions run asynchronously; actions are given a callback to send return values
[W] performEventAsync :: Event ((a -> IO ()) -> WidgetHost m ()) -> m (Event a)
```
Also see the "Connection to the real world" and "Time" sections in the `reflex` Quick Reference.

### XMLHttpRequest

Expand All @@ -178,16 +140,6 @@ Convenience functions for XMLHttpRequest. see Reflex.Dom.Xhr
[W] getAndDecode :: FromJSON a => Event Text -> m (Event (Maybe a))
```

### Time

```haskell
-- Create Event at given interval with given basis time.
[W] tickLossy :: NominalDiffTime -> UTCTime -> m (Event t TickInfo)

-- Delay an Event's occurrences by a given amount in seconds.
[W] delay :: NominalDiffTime -> Event t a -> m (Event t a)
```

## Startup

```haskell
Expand All @@ -201,7 +153,6 @@ Convenience functions for XMLHttpRequest. see Reflex.Dom.Xhr
[I] mainWidgetWithCss ::
ByteString ->
Widget Spider (Gui Spider (WithWebView SpiderHost) (HostFrame Spider)) () -> IO ()

-- One-shot Event that is triggered once all initial widgets are built
[W] getPostBuild :: m (Event ())
```

Also see the corresponding section in the `reflex` Quick Reference.
14 changes: 7 additions & 7 deletions reflex-dom-core/default.nix
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,10 @@
, bytestring, constraints, containers, contravariant, data-default
, dependent-map, dependent-sum, dependent-sum-template, directory
, exception-transformers, ghcjs-dom, hlint, jsaddle, keycode, lens
, monad-control, mtl, primitive, random, ref-tf, reflex, semigroups
, stdenv, stm, template-haskell, temporary, text, these, time
, transformers, unbounded-delays, unix, zenc, hashable
, chromium, process, jsaddle-warp, linux-namespaces, iproute
, monad-control, mtl, primitive, ref-tf, reflex, semigroups, stdenv
, stm, template-haskell, temporary, text, these, transformers
, unix, zenc, hashable, chromium, process, jsaddle-warp
, linux-namespaces, iproute
}:
let addGcTestDepends = drv: if stdenv.system != "x86_64-linux" then drv else drv // {
testHaskellDepends = (drv.testHaskellDepends or []) ++ [ temporary jsaddle-warp process linux-namespaces ];
Expand All @@ -19,9 +19,9 @@ in mkDerivation (addGcTestDepends {
aeson base bifunctors bimap blaze-builder bytestring constraints
containers contravariant data-default dependent-map dependent-sum
dependent-sum-template directory exception-transformers ghcjs-dom
jsaddle keycode lens monad-control mtl primitive random ref-tf
reflex semigroups stm template-haskell text these time transformers
unbounded-delays unix zenc
jsaddle keycode lens monad-control mtl primitive ref-tf
reflex semigroups stm template-haskell text these transformers
unix zenc
] ++ (if ghc.isGhcjs or false then [
hashable
] else []);
Expand Down
4 changes: 1 addition & 3 deletions reflex-dom-core/reflex-dom-core.cabal
Original file line number Diff line number Diff line change
Expand Up @@ -64,16 +64,13 @@ library
monad-control >= 1.0.1 && < 1.1,
mtl >= 2.1 && < 2.3,
primitive >= 0.5 && < 0.7,
random == 1.1.*,
ref-tf == 0.4.*,
reflex == 0.5.*,
semigroups >= 0.16 && < 0.19,
stm == 2.4.*,
text == 1.2.*,
these >= 0.4 && < 0.8,
time >= 1.4 && < 1.9,
transformers >= 0.3 && < 0.6,
unbounded-delays >= 0.1.0.9 && < 0.2,
zenc == 0.1.*

if impl(ghcjs)
Expand Down Expand Up @@ -152,6 +149,7 @@ test-suite hlint

test-suite gc
build-depends: base
, reflex
, reflex-dom-core
, jsaddle
, jsaddle-warp
Expand Down
2 changes: 1 addition & 1 deletion reflex-dom-core/src/Foreign/JavaScript/TH.hs
Original file line number Diff line number Diff line change
Expand Up @@ -136,7 +136,7 @@ instance PrimMonad m => PrimMonad (WithJSContextSingleton x m) where
type PrimState (WithJSContextSingleton x m) = PrimState m
primitive = lift . primitive

instance MonadAdjust t m => MonadAdjust t (WithJSContextSingleton x m) where
instance Adjustable t m => Adjustable t (WithJSContextSingleton x m) where
runWithReplace a0 a' = WithJSContextSingleton $ runWithReplace (coerce a0) (coerceEvent a')
traverseIntMapWithKeyWithAdjust f dm0 dm' = WithJSContextSingleton $ traverseIntMapWithKeyWithAdjust (\k v -> unWithJSContextSingleton $ f k v) (coerce dm0) (coerceEvent dm')
traverseDMapWithKeyWithAdjust f dm0 dm' = WithJSContextSingleton $ traverseDMapWithKeyWithAdjust (\k v -> unWithJSContextSingleton $ f k v) (coerce dm0) (coerceEvent dm')
Expand Down
2 changes: 1 addition & 1 deletion reflex-dom-core/src/Reflex/Dom/Builder/Class.hs
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ class Default (EventSpec d EventResult) => DomSpace d where

-- | @'DomBuilder' t m@ indicates that @m@ is a 'Monad' capable of building
-- dynamic DOM in the 'Reflex' timeline @t@
class (Monad m, Reflex t, DomSpace (DomBuilderSpace m), MonadAdjust t m) => DomBuilder t m | m -> t where
class (Monad m, Reflex t, DomSpace (DomBuilderSpace m), Adjustable t m) => DomBuilder t m | m -> t where
type DomBuilderSpace m :: *
textNode :: TextNodeConfig t -> m (TextNode (DomBuilderSpace m) t)
default textNode :: ( MonadTrans f
Expand Down
18 changes: 9 additions & 9 deletions reflex-dom-core/src/Reflex/Dom/Builder/Immediate.hs
Original file line number Diff line number Diff line change
Expand Up @@ -337,7 +337,7 @@ extractUpTo df s e = liftJSM $ do
void $ call f f (df, s, e)
#endif

type SupportsImmediateDomBuilder t m = (Reflex t, MonadJSM m, MonadHold t m, MonadFix m, MonadReflexCreateTrigger t m, MonadRef m, Ref m ~ Ref JSM, MonadAdjust t m, PrimMonad m)
type SupportsImmediateDomBuilder t m = (Reflex t, MonadJSM m, MonadHold t m, MonadFix m, MonadReflexCreateTrigger t m, MonadRef m, Ref m ~ Ref JSM, Adjustable t m, PrimMonad m)

{-# INLINABLE collectUpTo #-}
collectUpTo :: (MonadJSM m, IsNode start, IsNode end) => start -> end -> m DOM.DocumentFragment
Expand Down Expand Up @@ -400,7 +400,7 @@ wrap e cfg = do
}

{-# INLINABLE makeElement #-}
makeElement :: forall er t m a. (MonadJSM m, MonadFix m, MonadReflexCreateTrigger t m, MonadAdjust t m) => Text -> ElementConfig er t GhcjsDomSpace -> ImmediateDomBuilderT t m a -> ImmediateDomBuilderT t m ((Element er GhcjsDomSpace t, a), DOM.Element)
makeElement :: forall er t m a. (MonadJSM m, MonadFix m, MonadReflexCreateTrigger t m, Adjustable t m) => Text -> ElementConfig er t GhcjsDomSpace -> ImmediateDomBuilderT t m a -> ImmediateDomBuilderT t m ((Element er GhcjsDomSpace t, a), DOM.Element)
makeElement elementTag cfg child = do
doc <- askDocument
e <- liftJSM $ uncheckedCastTo DOM.Element <$> case cfg ^. namespace of
Expand Down Expand Up @@ -710,7 +710,7 @@ data ChildReadyStateInt
-- ^The child is not yet installed in the DOM and if it has unready children then the key into the unready count tracking 'DMap' is given.
deriving (Show, Read, Eq, Ord)

instance (Reflex t, MonadAdjust t m, MonadJSM m, MonadHold t m, MonadFix m, MonadRef m, Ref m ~ IORef, MonadReflexCreateTrigger t m, PrimMonad m) => MonadAdjust t (ImmediateDomBuilderT t m) where
instance (Reflex t, Adjustable t m, MonadJSM m, MonadHold t m, MonadFix m, MonadRef m, Ref m ~ IORef, MonadReflexCreateTrigger t m, PrimMonad m) => Adjustable t (ImmediateDomBuilderT t m) where
{-# INLINABLE runWithReplace #-}
runWithReplace a0 a' = do
initialEnv <- ImmediateDomBuilderT ask
Expand Down Expand Up @@ -845,7 +845,7 @@ instance (Reflex t, MonadAdjust t m, MonadJSM m, MonadHold t m, MonadFix m, Mona


{-# INLINABLE traverseDMapWithKeyWithAdjust' #-}
traverseDMapWithKeyWithAdjust' :: forall t m (k :: * -> *) v v'. (MonadAdjust t m, MonadHold t m, MonadFix m, MonadIO m, MonadJSM m, PrimMonad m, MonadRef m, Ref m ~ IORef, MonadReflexCreateTrigger t m, DMap.GCompare k) => (forall a. k a -> v a -> ImmediateDomBuilderT t m (v' a)) -> DMap k v -> Event t (PatchDMap k v) -> ImmediateDomBuilderT t m (DMap k v', Event t (PatchDMap k v'))
traverseDMapWithKeyWithAdjust' :: forall t m (k :: * -> *) v v'. (Adjustable t m, MonadHold t m, MonadFix m, MonadIO m, MonadJSM m, PrimMonad m, MonadRef m, Ref m ~ IORef, MonadReflexCreateTrigger t m, DMap.GCompare k) => (forall a. k a -> v a -> ImmediateDomBuilderT t m (v' a)) -> DMap k v -> Event t (PatchDMap k v) -> ImmediateDomBuilderT t m (DMap k v', Event t (PatchDMap k v'))
traverseDMapWithKeyWithAdjust' =
hoistTraverseWithKeyWithAdjust traverseDMapWithKeyWithAdjust mapPatchDMap updateChildUnreadiness applyDomUpdate_
where
Expand Down Expand Up @@ -879,7 +879,7 @@ traverseDMapWithKeyWithAdjust' =
liftIO $ writeIORef currentChildInstallations $! applyAlways (weakenPatchDMapWith (_child_installation . getCompose) $ PatchDMap p) childInstallations

{-# INLINABLE traverseIntMapWithKeyWithAdjust' #-}
traverseIntMapWithKeyWithAdjust' :: forall t m v v'. (MonadAdjust t m, MonadHold t m, MonadFix m, MonadIO m, MonadJSM m, PrimMonad m, MonadRef m, Ref m ~ IORef, MonadReflexCreateTrigger t m) => (IntMap.Key -> v -> ImmediateDomBuilderT t m v') -> IntMap v -> Event t (PatchIntMap v) -> ImmediateDomBuilderT t m (IntMap v', Event t (PatchIntMap v'))
traverseIntMapWithKeyWithAdjust' :: forall t m v v'. (Adjustable t m, MonadHold t m, MonadFix m, MonadIO m, MonadJSM m, PrimMonad m, MonadRef m, Ref m ~ IORef, MonadReflexCreateTrigger t m) => (IntMap.Key -> v -> ImmediateDomBuilderT t m v') -> IntMap v -> Event t (PatchIntMap v) -> ImmediateDomBuilderT t m (IntMap v', Event t (PatchIntMap v'))
traverseIntMapWithKeyWithAdjust' =
hoistTraverseIntMapWithKeyWithAdjust traverseIntMapWithKeyWithAdjust updateChildUnreadiness applyDomUpdate_
where
Expand Down Expand Up @@ -920,7 +920,7 @@ traverseIntMapWithKeyWithAdjust' =
-- adjust only versus adjust and move to the caller by way of its @applyDomUpdate_@ parameter.
{-# INLINABLE hoistTraverseIntMapWithKeyWithAdjust #-}
hoistTraverseIntMapWithKeyWithAdjust :: forall v v' t m p.
( MonadAdjust t m
( Adjustable t m
, MonadHold t m
, MonadIO m
, MonadJSM m
Expand All @@ -936,7 +936,7 @@ hoistTraverseIntMapWithKeyWithAdjust :: forall v v' t m p.
-> Event t (p v)
-> RequesterT t JSM Identity (TriggerEventT t m) (IntMap (Child ChildReadyStateInt v'), Event t (p (Child ChildReadyStateInt v')))
)
-- ^@base@: The base monad's 'MonadAdjust' traversal function to augment with DOM handling.
-- ^@base@: The base monad's 'Adjustable' traversal function to augment with DOM handling.
-> (p (Child ChildReadyStateInt v') -> IntMap (IORef ChildReadyStateInt) -> IO (IntMap (IORef ChildReadyStateInt)))
-- ^@updateChildUnreadiness@: Given a patch for the children DOM elements, produce a patch for the childrens' unreadiness state
-> (IORef (IntMap ChildInstallation) -> IORef DOM.Text -> p (Child ChildReadyStateInt v') -> JSM ())
Expand Down Expand Up @@ -1023,7 +1023,7 @@ hoistTraverseIntMapWithKeyWithAdjust base updateChildUnreadiness applyDomUpdate_
-- adjust only versus adjust and move to the caller by way of its @applyDomUpdate_@ parameter.
{-# INLINABLE hoistTraverseWithKeyWithAdjust #-}
hoistTraverseWithKeyWithAdjust :: forall (k :: * -> *) v v' t m p.
( MonadAdjust t m
( Adjustable t m
, MonadHold t m
, DMap.GCompare k
, MonadIO m
Expand All @@ -1043,7 +1043,7 @@ hoistTraverseWithKeyWithAdjust :: forall (k :: * -> *) v v' t m p.
-> Event t (p k vv)
-> RequesterT t JSM Identity (TriggerEventT t m) (DMap k vv', Event t (p k vv'))
)
-- ^@base@: The base monad's 'MonadAdjust' traversal function to augment with DOM handling.
-- ^@base@: The base monad's 'Adjustable' traversal function to augment with DOM handling.
-> (forall vv vv'. (forall a. vv a -> vv' a) -> p k vv -> p k vv')
-- ^@mapPatch@: A way of mapping over the patch type, e.g. 'mapPatchDMap' or 'mapPatchDMapWithMove'
-> (p k (Compose (Child (ChildReadyState k)) v') -> DMap k (Constant (IORef (ChildReadyState k))) -> IO (DMap k (Constant (IORef (ChildReadyState k)))))
Expand Down
2 changes: 1 addition & 1 deletion reflex-dom-core/src/Reflex/Dom/Builder/InputDisabled.hs
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ instance MonadReflexCreateTrigger t m => MonadReflexCreateTrigger t (InputDisabl
newEventWithTrigger = lift . newEventWithTrigger
newFanEventWithTrigger f = lift $ newFanEventWithTrigger f

instance MonadAdjust t m => MonadAdjust t (InputDisabledT m) where
instance Adjustable t m => Adjustable t (InputDisabledT m) where
runWithReplace a0 a' = InputDisabledT $ runWithReplace (coerce a0) (coerceEvent a')
traverseDMapWithKeyWithAdjust f dm0 dm' = InputDisabledT $ traverseDMapWithKeyWithAdjust (\k v -> runInputDisabledT $ f k v) (coerce dm0) (coerceEvent dm')
traverseDMapWithKeyWithAdjustWithMove f dm0 dm' = InputDisabledT $ traverseDMapWithKeyWithAdjustWithMove (\k v -> runInputDisabledT $ f k v) (coerce dm0) (coerceEvent dm')
Expand Down
8 changes: 4 additions & 4 deletions reflex-dom-core/src/Reflex/Dom/Builder/Static.hs
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ import Data.Dependent.Sum (DSum (..))
import Data.Functor.Compose
import Data.Functor.Constant
import qualified Data.Map as Map
import Data.Map.Misc (applyMap)
import Data.Monoid
import qualified Data.Set as Set
import Data.Text (Text)
Expand All @@ -41,7 +42,6 @@ import Data.Tuple
import GHC.Generics
import Reflex.Class
import Reflex.Dom.Builder.Class
import Reflex.Dom.Widget.Basic (applyMap)
import Reflex.Dynamic
import Reflex.Host.Class
import Reflex.PerformEvent.Base
Expand Down Expand Up @@ -122,7 +122,7 @@ instance MonadRef m => MonadRef (StaticDomBuilderT t m) where
instance MonadAtomicRef m => MonadAtomicRef (StaticDomBuilderT t m) where
atomicModifyRef r = lift . atomicModifyRef r

type SupportsStaticDomBuilder t m = (Reflex t, MonadIO m, MonadHold t m, MonadFix m, PerformEvent t m, MonadReflexCreateTrigger t m, MonadRef m, Ref m ~ Ref IO, MonadAdjust t m)
type SupportsStaticDomBuilder t m = (Reflex t, MonadIO m, MonadHold t m, MonadFix m, PerformEvent t m, MonadReflexCreateTrigger t m, MonadRef m, Ref m ~ Ref IO, Adjustable t m)

data StaticDomSpace

Expand All @@ -146,7 +146,7 @@ instance DomSpace StaticDomSpace where
type RawSelectElement StaticDomSpace = ()
addEventSpecFlags _ _ _ _ = StaticEventSpec

instance (Reflex t, MonadAdjust t m, MonadHold t m) => MonadAdjust t (StaticDomBuilderT t m) where
instance (Reflex t, Adjustable t m, MonadHold t m) => Adjustable t (StaticDomBuilderT t m) where
runWithReplace a0 a' = do
e <- StaticDomBuilderT ask
(result0, result') <- lift $ runWithReplace (runStaticDomBuilderT a0 e) (flip runStaticDomBuilderT e <$> a')
Expand All @@ -157,7 +157,7 @@ instance (Reflex t, MonadAdjust t m, MonadHold t m) => MonadAdjust t (StaticDomB
traverseDMapWithKeyWithAdjustWithMove = hoistDMapWithKeyWithAdjust traverseDMapWithKeyWithAdjustWithMove mapPatchDMapWithMove

hoistDMapWithKeyWithAdjust :: forall (k :: * -> *) v v' t m p.
( MonadAdjust t m
( Adjustable t m
, MonadHold t m
, PatchTarget (p k (Constant (Behavior t Builder))) ~ DMap k (Constant (Behavior t Builder))
, Patch (p k (Constant (Behavior t Builder)))
Expand Down
1 change: 0 additions & 1 deletion reflex-dom-core/src/Reflex/Dom/Core.hs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@ import Reflex.Dom.Modals.Base as X
import Reflex.Dom.Modals.Class as X
import Reflex.Dom.Old as X
import Reflex.Dom.Prerender as X
import Reflex.Dom.Time as X
import Reflex.Dom.WebSocket as X
import Reflex.Dom.Widget as X
import Reflex.Dom.Xhr as X
Loading